package com.syntaxtree.trees;

import java.util.ArrayList;
import java.util.List;
import com.comm.RegexHelper;
import com.syntaxtree.constant.Inherit;
import com.syntaxtree.constant.ModifierCharacter;
import com.syntaxtree.constant.Other;
import com.syntaxtree.constant.Visibility;

public class TypeTree extends BaseTree {
	/** 包名 */
	public String TypeNamespace;
	public String TypeName;
	public String TypeExtendsName;
	/** 类型可见性:public private protected default */
	public String TypeVisibility;
	public String TypeHeader;
	public String TypeBody;
	/** 类型种类:class interface enum */
	public String TypeCategory;
	public List<String> TypeImplementsList = new ArrayList<String>();
	public List<String> TypeImportList = new ArrayList<String>();
	public boolean IsFinal;
	public boolean IsAbstract;
	public boolean IsStrictfp;
	
	private final String packagePattern = "package\s+?[\\w.]+?;";
	private final String importPattner="import\s+?[\\w.]+?;";

	public TypeTree(String typeCode) {
		super(typeCode);
		initLocalVariable();
	}

	private void initLocalVariable() {
		this.TypeHeader = getTypeHeader(this.Code);
		this.TypeBody = getTypeBody(this.Code);
		this.TypeName = getTypeName(this.Code);
		this.TypeExtendsName = getTypeExtends(this.Code);
		this.TypeImplementsList = getTypeImplementsList(this.Code);
		String[] split = headerSplit(this.Code);
		this.TypeVisibility = Visibility.PRIVATE;
		this.IsFinal = false;
		this.IsStrictfp = false;
		this.TypeNamespace = getTypeNamespace(this.Code);
		this.TypeImportList=getTypeImportList(this.Code);
		for (int i = 0; i < split.length; i++) {
			if (split[i].equals(com.syntaxtree.constant.Type.CLASS))
				this.TypeCategory = com.syntaxtree.constant.Type.CLASS;
			else if (split[i].equals(com.syntaxtree.constant.Type.ENUM))
				this.TypeCategory = com.syntaxtree.constant.Type.ENUM;
			else if (split[i].equals(com.syntaxtree.constant.Type.INTERFACE))
				this.TypeCategory = com.syntaxtree.constant.Type.INTERFACE;
			if (split[i].equals(Visibility.PUBLIC))
				this.TypeVisibility = Visibility.PUBLIC;
			if (split[i].equals(Visibility.PRIVATE))
				this.TypeVisibility = Visibility.PRIVATE;
			if (split[i].equals(Visibility.PROTECTED))
				this.TypeVisibility = Visibility.PROTECTED;
			if (split[i].equals(Visibility.DEFAULT))
				this.TypeVisibility = Visibility.DEFAULT;
			if (split[i].equals(ModifierCharacter.FINAL))
				this.IsFinal = true;
			if (split[i].equals(ModifierCharacter.STRICTFP))
				this.IsStrictfp = true;
		}
	}

	private String getTypeNamespace(String typeCode) {
		List<String> list = RegexHelper.regex(typeCode, packagePattern);
		String packageStr = Other.Empty;
		if (list != null && list.size() > 0) {
			packageStr = list.get(0);
		}
		return packageStr;
	}

	private String getTypeHeader(String typeCode) {
		String headers = typeCode.substring(0, typeCode.indexOf('{'));
		headers=headers.replaceAll(importPattner,  Other.Empty);
		return headers.split(Other.SPACE + Inherit.EXTENDS + Other.SPACE)[0].trim();
	}

	private String getTypeExtends(String typeCode) {
		String heasers = typeCode.substring(0, typeCode.indexOf('{'));
		String extendsName = Other.Empty;
		String[] splitsByExtends = heasers.split(Other.SPACE + Inherit.EXTENDS + Other.SPACE);
		if (splitsByExtends.length == 2) {
			splitsByExtends = splitsByExtends[1].split(Other.SPACE + Inherit.IMPLEMENTS + Other.SPACE);
			extendsName = splitsByExtends[0].trim();
		}
		return extendsName;
	}

	private List<String> getTypeImplementsList(String typeCode) {
		String heasers = typeCode.substring(0, typeCode.indexOf('{'));
		String[] splitsByImplements = heasers.split(Other.SPACE + Inherit.IMPLEMENTS + Other.SPACE);
		List<String> typeImplementsList = new ArrayList<String>();
		if (splitsByImplements.length == 2) {
			splitsByImplements = splitsByImplements[1].split(",");
			for (int i = 0; i < splitsByImplements.length; i++) {
				typeImplementsList.add(splitsByImplements[i].trim());
			}
		}
		return typeImplementsList;
	}
	
	private List<String> getTypeImportList(String typeCode){
		List<String> list = RegexHelper.regex(typeCode, importPattner);
		if (list != null && list.size() > 0) {
			return list;
		}
		return new ArrayList<String>();
	}

	private String getTypeBody(String typeCode) {
		return typeCode.substring(typeCode.indexOf('{'));
	}

	private String getTypeName(String typeCode) {
		String[] split = headerSplit(typeCode);
		return split[split.length - 1];
	}

	private String[] headerSplit(String typeCode) {
		String typeHeader = getTypeHeader(typeCode);
		String[] split = typeHeader.split(" ");
		if (split.length < 2)
			throw new IllegalArgumentException(String.format("函数头(%s)异常", typeHeader));
		return split;
	}

	public void showInfo() {
		System.out.println(String.format("源代码:%s", this.Code));
		System.out.println(String.format("类型名:%s", this.TypeName));
		System.out.println(String.format("类型可见性:%s", this.TypeVisibility));
		System.out.println(String.format("类型父类:%s", this.TypeExtendsName));
		System.out.println(String.format("类型头:%s", this.TypeHeader));
		System.out.println(String.format("类型种类:%s", this.TypeCategory));
		System.out.println(String.format("类型体:%s", this.TypeBody));
		System.out.println(String.format("接口:%s", String.join(",", this.TypeImplementsList)));
		System.out.println(String.format("包名:%s", this.TypeNamespace));
		System.out.println(String.format("引用:%s", String.join(",", this.TypeImportList)));
		System.out.println(String.format("is abstract:%s", this.IsAbstract));
		System.out.println(String.format("is final:%s", this.IsFinal));
		System.out.println(String.format("is strictfp:%s", this.IsStrictfp));
	}
}
